import {EventEmitter, Injectable} from '@angular/core';
import {ArticleService} from '../services/article.service';
import {NzMessageService} from 'ng-zorro-antd/message';
import {Router} from '@angular/router';
import {NzUploadFile} from 'ng-zorro-antd/upload';

export interface ArticleInterface {
  id: number;
  user_id: number;
  type: '1' | '2';
  article_title: string;
  cover_img_url: NzUploadFile[];
  article_categorys: Array<string>;
  article_des: string;
  article_content: string;
  article_date: string | number;
  last_edit_date: string | number;
  article_views?: number;
}

@Injectable()

export class ArticlesManagerService {
  public articles: Array<ArticleInterface> = [];
  public articlesChange = new EventEmitter();
  constructor(
    private articleService: ArticleService,
    private message: NzMessageService,
    private router: Router
  ) { }

  /**
   * @description 新增文章
   * @param {ArticleInterface} v
   */
  public addArticle(v: ArticleInterface): void {
    const temp: any = v;
    if (temp.cover_img_url instanceof Array) {
      temp.cover_img_url = JSON.stringify(temp.cover_img_url);
    }
    this.articleService.createArticle(temp, (res) => {
      this.message.create('success', res.message);
      this.articleService.getLastCreate({}, (data) => {
        this.articles.unshift(data.content[0]);
        this.router.navigateByUrl('/main/manager');
      }, (err) => {
        this.message.create('error', '获取最新发布文章失败！');
      });
    }, (err) => {
      this.message.create('success', '发布失败');
      console.log(err);
    });
  }

  /**
   * @description 删除文章
   * @param {number} id
   */
  public delArticle(id: number): void {
    this.articleService.deleteArticleById({id}, (res) => {
      this.message.create('success', res.message);
      this.articles = this.articles.filter((item) => {
        return item.id !== id;
      });
      this.articlesChange.emit(this.articles);
    }, (err) => {});
  }

  /**
   * @description 更新文章
   * @param { ArticleInterface } v
   * @param { number } index 本地的下标
   */
  public updateArticle(v: ArticleInterface): void {
    const temp: any = v;
    if (temp.cover_img_url instanceof Array) {
      temp.cover_img_url = JSON.stringify(temp.cover_img_url);
    }
    const localIndex = this.getArticleIndexById(v.id);
    if (localIndex === -1) {
      // 本地不存在， 直接走新增逻辑
      this.addArticle(v);
      return;
    }
    this.articleService.updateArticle(v, (res) => {
      this.articles[localIndex] = v;
      this.message.create('success', '更新成功！');
      this.articlesChange.emit(this.articles);
    }, (err) => {
      this.message.create('success', '更新失败');
      console.log(err);
    });
  }



  /**
   * @description 获取文章数据列表
   */
  public getArticles(): any {
    if (this.articles.length) {
      return this.articles;
    }
    this.updateArticles();
  }

  /**
   * @description 获取详情
   */
  public getArticleDetail(id, success?): void {
    const info = this.getArticleInfoById(id);
    this.articleService.getArticleDetail({ id }, (res) => {
      Object.assign(info, res.content[0]);
      if (success instanceof Function) { success(info); }
    }, (err) => {
      this.message.create('error', '获取文章详情失败！');
    });
  }

  /**
   * @description 销毁服务
   */
  public destroy(): void {
    this.articles.splice(0);
  }

  /**
   * @description 更新文章数据列表
   * @param success 成功回调
   */
  private updateArticles(success?): void {
    this.articleService.readArticles({}, (res) => {
      this.articles = res.content;
      this.articlesChange.emit(this.articles);
      if (success instanceof Function) { success(); }
    }, (err) => {
      this.articles = [];
      this.articlesChange.emit(this.articles);
      this.message.create('error', '获取文章列表失败！');
    });
  }

  /**
   * @description 通过id查询本地文章信息
   * @param id
   */
  private getArticleInfoById(id: number): ArticleInterface {
    const index = this.getArticleIndexById(id);
    if (index !== -1) {
      return this.articles[index];
    }
    throw new Error('数据异常');
  }

  /**
   * @description 通过id查询本地文章下标
   */
  private getArticleIndexById(id: number): number {
    for (let i = 0, len = this.articles.length; i < len; i++) {
      if (this.articles[i].id === id) {
        return i;
      }
    }
    return -1;
  }
}
